export const createStore = (reducer, enhancer) => {
    if (enhancer) {
        return enhancer(createStore)(reducer)
    }
    let currentState = {}
    let currentListener = []

    function getState() {
        return currentState
    }
    function subscribe(listener) {
        currentListener.push(listener)
    }
    function dispatch(action) {
        currentState = reducer(currentState, action)
        currentListener.forEach(v => v())
        return action
    }
    dispatch({type:'@srtian/init'})
    return { getState, subscribe, dispatch}
}

export const applyMiddleWare = (middleware) => {
    return createStore => (...args) => {
        const store = createStore(...args)
        const dispatch = store.dispatch
        const middleAPI = {
            getState: store.getState,
            dispatch: (...args) => dispatch(...args)
        }
        const chain = middleware.map(middleware => middleware(middleAPI))
        dispatch = compose(...chain)(store.dispatch)
    }
    return {
        ...store,
        dispatch
    }
}

export const compose = (...funcs) => {
    if (funcs.length == 0) {
        return arg => arg
    }
    if (funcs.length == 1) {
        return funcs[0]
    }
    return funcs.reduce((fn1, fn2) => (...args) => fn1(fn2(...args)))
}

export const combineReducers = (reducers) => {
    return (state={}, action) => {
        let newState = {}
        for (let key in reducers) {
            newState[key] = reducers[key](state[key], action)
        }
        return newState
    }
}
const bindActionCreator = (creator, dispatch) => {
    return (...args) => dispatch(creator(...args))
}
 export const bindActionCreators = (creator, dispatch) => {
     let bound = {}
     Object.keys(creator).forEach(v => {
         let creator = creator[v]
         bound[v] = bindActionCreator(creator, dispatch)
     })
     return bound
 }
















